<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { Deployment, PodTemplateSpec } from "../../../../api/k8s/types";
import { InjectLabelKey } from "@/views/domain/kubeHud/api/k8s/defination";
import { useDeploymentEditor } from "./createProvider";
import { isEqual } from "@pureadmin/utils";

const { editContext, podAffinityOption, podAntiAffinityOption } =
  useDeploymentEditor();

const affinity = computed(() => {
  return editContext.editDeployment.value.spec.template.spec.affinity;
});

type AffinityType = "distribute" | "default" | "cluster" | "custom";
type AffinityOption = {
  type?: AffinityType;
  title?: string;
  description?: string;
  icon?: any;
};

type CustomRule = {
  type?: "affinity" | "anti-affinity";
  policy?: "required" | "preferred";
  target?: string; // deployment name
};

// 自定义规则
const customRules = ref<CustomRule[]>([]);

// 当前选项
const currentOption = ref<AffinityType>();

// 初始化选项
const options = ref<AffinityOption[]>([
  {
    type: "distribute",
    title: "分散调度",
    description: "尽可能调度到不同节点上"
  },
  {
    type: "cluster",
    title: "集中调度",
    description: "尽可能调度到相同节点上"
  },
  {
    type: "default",
    title: "默认规则",
    description: "默认调度规则"
  },
  {
    type: "custom",
    title: "自定义规则",
    description: "自定义调度规则"
  }
]);

const parseAffinityType = () => {
  if (
    isEqual(
      podAffinityOption(editContext.editDeployment.value.metadata.name),
      affinity.value
    )
  ) {
    // 亲和
    currentOption.value = "cluster";
  } else if (
    isEqual(
      podAntiAffinityOption(editContext.editDeployment.value.metadata.name),
      affinity.value
    )
  ) {
    // 反亲和
    currentOption.value = "distribute";
  } else if (isEqual(affinity.value, {})) {
    currentOption.value = "default";
  } else {
    currentOption.value = "custom";
  }
};

// 切换选项
const onOptionChange = (type?: AffinityType) => {
  switch (type) {
    case "distribute":
      editContext.setDefaultPodAffinity();
      break;
    case "cluster":
      editContext.setDefaultPodAntiAffinity();
      break;
    case "default":
    case "custom":
      editContext.editDeployment.value.spec.template.spec.affinity = {};
      break;
  }
};

const getOptionFromType = (type: AffinityType): AffinityOption => {
  return options.value.find(opt => opt.type === type);
};

onMounted(() => {
  parseAffinityType();
});
</script>

<template>
  <div class="pod-affinity-selector">
    <el-select
      v-model="currentOption"
      class="affinity-selector"
      @change="onOptionChange"
    >
      <el-option
        v-for="opt in options"
        :key="opt.type"
        :label="opt.title"
        :value="opt.type"
      >
        <div class="flex flex-col">
          <span class="selector-title">{{ opt.title }}</span>
          <span class="selector-desc"> {{ opt.description }} </span>
        </div>
      </el-option>
      <template #label="{ label, value }">
        <div class="flex flex-col">
          <span class="selector-title">{{ label }}</span>
          <span class="selector-desc">
            {{ getOptionFromType(value)?.description }}
          </span>
        </div>
      </template>
    </el-select>
    <div v-if="currentOption === 'custom'" class="custom-rule-wrapper">
      <el-row />
    </div>
  </div>
</template>
<style lang="scss" scoped>
.pod-affinity-selector {
  display: flex;
  flex-direction: column;
  width: 100%;

  .affinity-selector {
    :deep(.el-select__wrapper) {
      min-height: 60px;
    }
  }
}
.custom-rule-wrapper {
  margin-top: 10px;
  padding: 10px;
  border-radius: 10px;
  background-color: var(--el-bg-color-page);
}
.selector-title {
  font-size: 14px;
  font-weight: bold;
}

.selector-desc {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
</style>
